﻿using Se.Common;
using Se.Log;
using Se.Model.Host;
using Se.Model.Data;
using Se.Model.GameModel.Character;
using Se.Model.Generator;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Se.Model.Template;
using Se.Model.Template.Common;

namespace SeServer.Module.Character
{
    /// <summary>
    /// 玩家Controller
    /// </summary>
    public class PlayerController : ModuleControllerBase
    {

        const ControllerType M_TYPE = ControllerType.Player;

        private MultiKeyDictionary<long, string, Player> m_PlayerSet;

        private MultiKeyDictionary<long, string, PlayerSim> m_SimPlayerSet;

        private HeaderTemplate[] m_HeaderTemplate;

        /// <summary>
        /// 敏感词
        /// </summary>
        private string[] m_IlligalWords;

        public PlayerController()
            : base(M_TYPE)
        {
            this.m_PlayerSet = new MultiKeyDictionary<long, string, Player>();
            this.m_SimPlayerSet = new MultiKeyDictionary<long, string, PlayerSim>();
        }

        #region interface PlayerController

        public override void InitModule()
        {
            DataEntityFactory.TryRegisterEntityCollection(typeof(Player), Se.Data.DBLoadType.MemoryThenDB);
            DataEntityFactory.TryRegisterEntityCollection(typeof(PlayerSim), Se.Data.DBLoadType.MemoryAlways);
        }

        /// <summary>
        /// 加载模板
        /// </summary>
        public override void LoadTemplates()
        {
            var entity = System.Activator.CreateInstance<HeaderTemplate>();
            this.m_IlligalWords = GameTemplateManager.Current.ReadFileToDB<IlligalWordTemplate>().Select(c => c.Words).ToArray();
            this.m_HeaderTemplate = GameTemplateManager.Current.ReadFileToDB<HeaderTemplate>();
        }

        public override void LoadPlayerData(Player player)
        {

        }

        public override void LoadMemoryData()
        {
            this.m_PlayerSet = new MultiKeyDictionary<long, string, Player>();
            this.m_SimPlayerSet = new MultiKeyDictionary<long, string, PlayerSim>();

            var simPlayers = DataEntityFactory.GetEntity<PlayerSim>();
            foreach (var simPlayer in simPlayers)
            {
                this.m_SimPlayerSet.Add(simPlayer.ID, simPlayer.Name, simPlayer);
            }
        }

        #endregion


        /// <summary>
        /// 创建玩家
        /// </summary>
        /// <param name="account"></param>
        /// <param name="gender"></param>
        /// <param name="headerId"></param>
        /// <returns></returns>
        private Player CreatePlayer(Account account, string playerName, PlayerGender gender, short headerId = 0)
        {
            Player player = new Player() { Name = playerName, Gender = gender, HeaderID = headerId };
            player.SetAccount(account);
            player.Save<Player>();
            return player;
        }

        /// <summary>
        /// 创建玩家
        /// </summary>
        public Player CreatePlayer(SocketSession session, Account account, string playerName, int roleTypeID)
        {
            if (account == null) return null;

            if (this.m_IlligalWords.Contains(playerName))
            {
                SeLog.Warn("PlayerController->CreatePlayer playername:{0} is illigal", playerName);
                PS_Send.ErrorInfo(session, 1, "名字不合法");
                return null;
            }
            if (this.m_PlayerSet.ContrainSubKey(playerName))
            {
                PS_Send.ErrorInfo(session, 1, "此名字已经存在");
                return null;
            }
            Player player = this.CreatePlayer(account, playerName, PlayerGender.Male, (short)roleTypeID);
            player.Session = session;
            this.m_PlayerSet.Add(player.ID, player.Name, player);
            session.SetPlayer(player);

            GameGlobalEvent.OnCreatePlayer(player);

            return player;
        }

        /// <summary>
        /// 登录
        /// </summary>
        /// <param name="session"></param>
        /// <param name="account"></param>
        /// <param name="player"></param>
        /// <returns></returns>
        public void Login(SocketSession session, Account account, long playerID)
        {
            if (session.State != SessionState.LoginAccount) return;

            Player player;
            if (!this.m_PlayerSet.TryGetValue(playerID, out player)) return;

            if (player.OnlineState != OnlineState.OutWorld)
            {
                this.Logout(player);
            }
            player.Session = session;
            player.OnLogin();

            GameGlobalEvent.OnLoginPlayer(player);
        }

        /// <summary>
        /// 登出
        /// </summary>
        /// <param name="player"></param>
        public void Logout(Player player)
        {
            player.OnLogout();
        }


        public Player GetPlayer(string name)
        {
            Player player = null;
            if (!this.m_PlayerSet.TryGetValue(name, out player))
            {
                //TODO 从DB中加载Player
            }

            return player;
        }

        public Player GetPlayer(long id)
        {
            Player player = null;
            this.m_PlayerSet.TryGetValue(id, out player);
            player = DataEntityFactory.GetEntity<Player>(id);

            return player;
        }

    }
}
